import { Editor } from '@monaco-editor/react';
import {
  Alert,
  Box,
  Container,
  Stack,
  Tab,
  Tabs,
  Typography,
  Paper,
  Grid,
  Link,
  List,
  ListItem,
} from '@mui/material';
import { FC, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import Layout from '../../components/Layout';

interface TabPanelProps {
  children?: React.ReactNode;
  index: number;
  value: number;
}

const TabPanel: FC<TabPanelProps> = props => {
  const { children, value, index, ...other } = props;

  return (
    <div role="tabpanel" hidden={value !== index} {...other}>
      {value === index && <Box sx={{ p: 3 }}>{children}</Box>}
    </div>
  );
};

// 动态导入示例
const dynamicImportExample = `// 动态导入示例
async function loadComponent() {
  try {
    const module = await import('./components/MyComponent');
    return module.default;
  } catch (error) {
    console.error('组件加载失败:', error);
    return null;
  }
}

// 条件加载示例
const shouldLoadModule = true;
if (shouldLoadModule) {
  import('./utils/helper').then(module => {
    module.doSomething();
  });
}

// ES6 模块系统示例
export const PI = 3.14159;
export function add(a: number, b: number) {
  return a + b;
}

// CommonJS 模块系统示例
const config = {
  apiUrl: 'https://api.example.com'
};
module.exports = config;`;

const CodeBlock = ({ children }: { children: string }) => (
  <Paper
    sx={{
      p: 3,
      my: 2,
      bgcolor: '#1e1e1e',
      borderRadius: 2,
      boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
      '& pre': {
        margin: 0,
        padding: 0,
        fontFamily: '"Fira Code", "Consolas", monospace',
        fontSize: '0.9rem',
        lineHeight: 1.5,
        color: '#d4d4d4',
        whiteSpace: 'pre-wrap',
        wordWrap: 'break-word',
      },
      '& code': {
        color: '#d4d4d4',
      },
      position: 'relative',
      '&:hover': {
        '&::after': {
          content: '"复制"',
          position: 'absolute',
          top: 8,
          right: 8,
          padding: '4px 8px',
          borderRadius: 4,
          backgroundColor: 'rgba(255, 255, 255, 0.1)',
          color: '#fff',
          fontSize: '0.75rem',
          cursor: 'pointer',
          transition: 'all 0.2s',
          '&:hover': {
            backgroundColor: 'rgba(255, 255, 255, 0.2)',
          },
        },
      },
    }}
  >
    <pre>{children}</pre>
  </Paper>
);

const JavaScriptBasics: React.FC = () => {
  const location = useLocation();
  const navigate = useNavigate();
  const [selectedPath, setSelectedPath] = useState('variables');
  const currentHash = location.hash.slice(1);

  const handleNavigation = (path: string, isMainItem = false) => {
    if (isMainItem) {
      setSelectedPath(path);
    }
    window.location.hash = path;
  };

  const menuItems = [
    {
      title: '变量和数据类型',
      path: 'variables',
      subItems: [
        { title: '变量声明', id: 'variables-declaration' },
        { title: '数据类型', id: 'data-types' },
        { title: '类型转换', id: 'type-conversion' },
      ],
    },
    {
      title: '运算符和表达式',
      path: 'operators',
      subItems: [
        { title: '算术运算符', id: 'arithmetic-operators' },
        { title: '比较运算符', id: 'comparison-operators' },
        { title: '逻辑运算符', id: 'logical-operators' },
      ],
    },
    {
      title: '控制流程',
      path: 'control-flow',
      subItems: [
        { title: '条件语句', id: 'conditional-statements' },
        { title: '循环语句', id: 'loops' },
        { title: '异常处理', id: 'error-handling' },
      ],
    },
    {
      title: '函数',
      path: 'functions',
      subItems: [
        { title: '函数声明', id: 'function-declaration' },
        { title: '函数参数', id: 'function-parameters' },
        { title: '箭头函数', id: 'arrow-functions' },
      ],
    },
    {
      title: '数组和对象',
      path: 'arrays-objects',
      subItems: [
        { title: '数组操作', id: 'array-operations' },
        { title: '对象操作', id: 'object-operations' },
        { title: '解构赋值', id: 'destructuring' },
      ],
    },
  ];

  const TableOfContents = () => (
    <Box sx={{ position: 'sticky', top: 20, bgcolor: '#f5f5f5', p: 2, borderRadius: 1 }}>
      <Typography variant="h6" gutterBottom>
        目录
      </Typography>
      <List dense>
        {menuItems.map(item => (
          <Box key={item.path}>
            <ListItem sx={{ cursor: 'pointer' }} onClick={() => handleNavigation(item.path, true)}>
              <Link
                component="span"
                sx={{
                  color: selectedPath === item.path ? '#1976d2' : 'inherit',
                  textDecoration: 'none',
                  '&:hover': { textDecoration: 'underline' },
                }}
              >
                {item.title}
              </Link>
            </ListItem>
            {item.subItems && selectedPath === item.path && (
              <List sx={{ pl: 2 }}>
                {item.subItems.map(subItem => (
                  <ListItem key={subItem.id}>
                    <Link
                      component="span"
                      onClick={() => handleNavigation(subItem.id)}
                      sx={{
                        color: currentHash === subItem.id ? '#1976d2' : 'text.secondary',
                        textDecoration: 'none',
                        cursor: 'pointer',
                        '&:hover': { textDecoration: 'underline' },
                      }}
                    >
                      {subItem.title}
                    </Link>
                  </ListItem>
                ))}
              </List>
            )}
          </Box>
        ))}
      </List>
    </Box>
  );

  const getContent = () => {
    switch (selectedPath) {
      case 'variables':
        return (
          <Box>
            <Typography variant="h4" gutterBottom id="variables">
              变量和数据类型
            </Typography>
            <Typography paragraph>
              JavaScript是一门灵活的编程语言，变量可以持有不同类型的值。理解变量声明、数据类型和类型转换是掌握JavaScript的基础。
            </Typography>
            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="variables-declaration">
                变量声明
              </Typography>
              <Typography paragraph>在JavaScript中，我们使用let、const和var来声明变量：</Typography>
              <CodeBlock>{`// 使用let声明变量
let message = "Hello World";

// 使用const声明常量
const PI = 3.14159;

// 使用var（不推荐）
var oldWay = "legacy code";`}</CodeBlock>
            </Box>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="data-types">
                数据类型
              </Typography>
              <Typography paragraph>JavaScript中有以下基本数据类型：</Typography>
              <List>
                <ListItem>
                  <Typography>
                    <strong>Number：</strong> 包括整数和浮点数（如：42, 3.14）
                  </Typography>
                </ListItem>
                <ListItem>
                  <Typography>
                    <strong>String：</strong> 文本字符串（如：&quot;Hello&quot;, &apos;World&apos;）
                  </Typography>
                </ListItem>
                <ListItem>
                  <Typography>
                    <strong>Boolean：</strong> true 或 false
                  </Typography>
                </ListItem>
                <ListItem>
                  <Typography>
                    <strong>null：</strong> 表示空值
                  </Typography>
                </ListItem>
                <ListItem>
                  <Typography>
                    <strong>undefined：</strong> 未定义的值
                  </Typography>
                </ListItem>
              </List>
            </Box>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="type-conversion">
                类型转换
              </Typography>
              <Typography paragraph>JavaScript提供了多种类型转换的方法：</Typography>
              <CodeBlock>{`// 字符串转数字
const num1 = Number("42");     // 42
const num2 = parseInt("42");   // 42
const num3 = +"42";           // 42

// 数字转字符串
const str1 = String(42);      // "42"
const str2 = 42.toString();   // "42"

// 转布尔值
const bool1 = Boolean("");    // false
const bool2 = !!"";          // false
const bool3 = Boolean("42");  // true`}</CodeBlock>
            </Box>
          </Box>
        );

      case 'operators':
        return (
          <Box>
            <Typography variant="h4" gutterBottom id="operators">
              运算符和表达式
            </Typography>
            <Typography paragraph>
              JavaScript中的运算符用于执行各种操作，包括算术运算、比较和逻辑运算。
            </Typography>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="arithmetic-operators">
                算术运算符
              </Typography>
              <Typography paragraph>用于执行基本的数学运算：</Typography>
              <CodeBlock>{`// 基本算术运算符
const sum = 5 + 3;      // 加法: 8
const diff = 10 - 4;    // 减法: 6
const product = 3 * 4;  // 乘法: 12
const quotient = 15 / 3;// 除法: 5
const remainder = 17 % 5;// 取余: 2

// 递增和递减
let count = 0;
count++;               // 后递增
++count;              // 前递增
count--;              // 后递减
--count;              // 前递减`}</CodeBlock>
            </Box>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="comparison-operators">
                比较运算符
              </Typography>
              <Typography paragraph>用于比较两个值：</Typography>
              <CodeBlock>{`// 相等性比较
console.log(5 == "5");   // true（宽松相等）
console.log(5 === "5");  // false（严格相等）
console.log(5 != "5");   // false（宽松不等）
console.log(5 !== "5");  // true（严格不等）

// 大小比较
console.log(10 > 5);     // true（大于）
console.log(5 >= 5);     // true（大于等于）
console.log(3 < 7);      // true（小于）
console.log(3 <= 3);     // true（小于等于）`}</CodeBlock>
            </Box>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="logical-operators">
                逻辑运算符
              </Typography>
              <Typography paragraph>用于组合和操作布尔值：</Typography>
              <CodeBlock>{`// 逻辑与（&&）
console.log(true && true);   // true
console.log(true && false);  // false

// 逻辑或（||）
console.log(true || false);  // true
console.log(false || false); // false

// 逻辑非（!）
console.log(!true);          // false
console.log(!false);         // true

// 短路求值
const name = user?.name || "默认名称";`}</CodeBlock>
            </Box>
          </Box>
        );

      case 'control-flow':
        return (
          <Box>
            <Typography variant="h4" gutterBottom id="control-flow">
              控制流程
            </Typography>
            <Typography paragraph>
              控制流程语句允许我们根据不同的条件执行不同的代码块，或重复执行某些代码。
            </Typography>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="conditional-statements">
                条件语句
              </Typography>
              <Typography paragraph>使用if...else和switch语句进行条件判断：</Typography>
              <Paper
                sx={{
                  p: 2,
                  bgcolor: '#f5f5f5',
                  '& pre': { margin: 0, fontFamily: 'monospace', fontSize: '0.9rem' },
                }}
              >
                <pre>{`// if...else 语句
const age = 18;
if (age >= 18) {
    console.log("成年人");
} else if (age >= 12) {
    console.log("青少年");
} else {
    console.log("儿童");
}

// switch 语句
const day = "Monday";
switch (day) {
    case "Monday":
        console.log("星期一");
        break;
    case "Tuesday":
        console.log("星期二");
        break;
    default:
        console.log("其他日期");
}`}</pre>
              </Paper>
            </Box>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="loops">
                循环语句
              </Typography>
              <Typography paragraph>使用不同类型的循环来重复执行代码：</Typography>
              <Paper
                sx={{
                  p: 2,
                  bgcolor: '#f5f5f5',
                  '& pre': { margin: 0, fontFamily: 'monospace', fontSize: '0.9rem' },
                }}
              >
                <pre>{`// for 循环
for (let i = 0; i < 5; i++) {
    console.log(i);
}

// while 循环
let count = 0;
while (count < 5) {
    console.log(count);
    count++;
}

// for...of 循环（用于数组）
const numbers = [1, 2, 3];
for (const num of numbers) {
    console.log(num);
}

// for...in 循环（用于对象）
const person = { name: "张三", age: 25 };
for (const key in person) {
    console.log(\`\${key}: \${person[key]}\`);
}`}</pre>
              </Paper>
            </Box>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="error-handling">
                异常处理
              </Typography>
              <Typography paragraph>使用try...catch处理代码执行过程中的错误：</Typography>
              <Paper
                sx={{
                  p: 2,
                  bgcolor: '#f5f5f5',
                  '& pre': { margin: 0, fontFamily: 'monospace', fontSize: '0.9rem' },
                }}
              >
                <pre>{`// 基本的错误处理
try {
    // 可能会抛出错误的代码
    throw new Error("发生了一个错误");
} catch (error) {
    console.error("捕获到错误:", error.message);
} finally {
    console.log("总是会执行的代码");
}

// 自定义错误
class ValidationError extends Error {
    constructor(message) {
        super(message);
        this.name = "ValidationError";
    }
}`}</pre>
              </Paper>
            </Box>
          </Box>
        );

      case 'functions':
        return (
          <Box>
            <Typography variant="h4" gutterBottom id="functions">
              函数
            </Typography>
            <Typography paragraph>
              函数是JavaScript中的基本构建块，它们允许我们封装可重用的代码块。
            </Typography>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="function-declaration">
                函数声明
              </Typography>
              <Typography paragraph>在JavaScript中声明函数的几种方式：</Typography>
              <Paper
                sx={{
                  p: 2,
                  bgcolor: '#f5f5f5',
                  '& pre': { margin: 0, fontFamily: 'monospace', fontSize: '0.9rem' },
                }}
              >
                <pre>{`// 函数声明
function greet(name) {
    return \`你好，\${name}！\`;
}

// 函数表达式
const greet = function(name) {
    return \`你好，\${name}！\`;
};

// 箭头函数
const greet = (name) => \`你好，\${name}！\`;

// 立即执行函数（IIFE）
(function() {
    console.log("立即执行");
})();`}</pre>
              </Paper>
            </Box>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="function-parameters">
                函数参数
              </Typography>
              <Typography paragraph>函数参数的高级特性：</Typography>
              <Paper
                sx={{
                  p: 2,
                  bgcolor: '#f5f5f5',
                  '& pre': { margin: 0, fontFamily: 'monospace', fontSize: '0.9rem' },
                }}
              >
                <pre>{`// 默认参数
function greet(name = "访客") {
    return \`你好，\${name}！\`;
}

// 剩余参数
function sum(...numbers) {
    return numbers.reduce((total, num) => total + num, 0);
}

// 参数解构
function printUserInfo({ name, age }) {
    console.log(\`\${name} 今年 \${age} 岁\`);
}

// 回调函数
function fetchData(callback) {
    setTimeout(() => {
        callback("数据");
    }, 1000);
}`}</pre>
              </Paper>
            </Box>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="arrow-functions">
                箭头函数
              </Typography>
              <Typography paragraph>箭头函数的特性和使用场景：</Typography>
              <Paper
                sx={{
                  p: 2,
                  bgcolor: '#f5f5f5',
                  '& pre': { margin: 0, fontFamily: 'monospace', fontSize: '0.9rem' },
                }}
              >
                <pre>{`// 基本语法
const add = (a, b) => a + b;

// 多行箭头函数
const multiply = (a, b) => {
    const result = a * b;
    return result;
};

// 箭头函数和this
const person = {
    name: "张三",
    greet: () => {
        console.log(this.name); // undefined
    },
    greetRegular: function() {
        console.log(this.name); // "张三"
    }
};

// 在数组方法中使用
const numbers = [1, 2, 3];
const doubled = numbers.map(num => num * 2);`}</pre>
              </Paper>
            </Box>
          </Box>
        );

      case 'arrays-objects':
        return (
          <Box>
            <Typography variant="h4" gutterBottom id="arrays-objects">
              数组和对象
            </Typography>
            <Typography paragraph>
              数组和对象是JavaScript中最常用的两种复杂数据类型，它们用于存储和组织数据。
            </Typography>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="array-operations">
                数组操作
              </Typography>
              <Typography paragraph>常用的数组方法和操作：</Typography>
              <Paper
                sx={{
                  p: 2,
                  bgcolor: '#f5f5f5',
                  '& pre': { margin: 0, fontFamily: 'monospace', fontSize: '0.9rem' },
                }}
              >
                <pre>{`// 创建和修改数组
const fruits = ["苹果", "香蕉"];
fruits.push("橙子");         // 添加到末尾
fruits.unshift("草莓");      // 添加到开头
fruits.pop();               // 移除最后一个
fruits.shift();            // 移除第一个

// 数组方法
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(x => x * 2);
const evens = numbers.filter(x => x % 2 === 0);
const sum = numbers.reduce((a, b) => a + b, 0);

// 数组查找
const index = fruits.indexOf("香蕉");
const found = fruits.find(f => f === "香蕉");
const exists = fruits.includes("香蕉");

// 数组排序
fruits.sort();                     // 字母顺序
numbers.sort((a, b) => a - b);    // 数字顺序`}</pre>
              </Paper>
            </Box>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="object-operations">
                对象操作
              </Typography>
              <Typography paragraph>对象的基本操作和高级特性：</Typography>
              <Paper
                sx={{
                  p: 2,
                  bgcolor: '#f5f5f5',
                  '& pre': { margin: 0, fontFamily: 'monospace', fontSize: '0.9rem' },
                }}
              >
                <pre>{`// 创建和访问对象
const person = {
    name: "张三",
    age: 25,
    greet() {
        return \`你好，我是\${this.name}\`;
    }
};

// 对象方法
const keys = Object.keys(person);
const values = Object.values(person);
const entries = Object.entries(person);

// 对象合并
const defaults = { theme: "light" };
const settings = { language: "zh" };
const config = { ...defaults, ...settings };

// 对象冻结和密封
Object.freeze(person);    // 完全冻结
Object.seal(person);     // 允许修改现有属性`}</pre>
              </Paper>
            </Box>

            <Box component="section" mt={3}>
              <Typography variant="h5" gutterBottom id="destructuring">
                解构赋值
              </Typography>
              <Typography paragraph>使用解构简化数组和对象的处理：</Typography>
              <Paper
                sx={{
                  p: 2,
                  bgcolor: '#f5f5f5',
                  '& pre': { margin: 0, fontFamily: 'monospace', fontSize: '0.9rem' },
                }}
              >
                <pre>{`// 数组解构
const [first, second, ...rest] = [1, 2, 3, 4, 5];
const [x = 0, y = 0] = [1];    // 默认值

// 对象解构
const { name, age } = person;
const { name: userName } = person;  // 重命名
const { theme = "dark" } = settings;// 默认值

// 嵌套解构
const data = {
    user: {
        profile: {
            name: "张三",
            social: {
                twitter: "@zhangsan"
            }
        }
    }
};
const { user: { profile: { social: { twitter } } } } = data;`}</pre>
              </Paper>
            </Box>
          </Box>
        );

      default:
        return (
          <Box>
            <Typography variant="h4" gutterBottom>
              JavaScript基础教程
            </Typography>
            <Typography variant="body1" paragraph>
              欢迎来到JavaScript基础教程。在这里，你将学习JavaScript的核心概念和基础知识。
            </Typography>
            <Typography variant="body1" paragraph>
              请从左侧菜单选择要学习的主题，或从右侧目录快速导航到具体内容。
            </Typography>
            <List>
              {menuItems.map(item => (
                <ListItem key={item.path}>
                  <Box>
                    <Typography variant="h6">{item.title}</Typography>
                    <Typography variant="body2" color="text.secondary">
                      {item.subItems.map(sub => sub.title).join('、')}
                    </Typography>
                  </Box>
                </ListItem>
              ))}
            </List>
          </Box>
        );
    }
  };

  return (
    <Layout>
      <Grid container spacing={3} sx={{ maxWidth: '1200px', margin: '0 auto', p: 3 }}>
        <Grid item xs={12} md={9}>
          {getContent()}
        </Grid>
        <Grid item xs={12} md={3}>
          <TableOfContents />
        </Grid>
      </Grid>
    </Layout>
  );
};

const _c = TabPanel;
const _c2 = JavaScriptBasics;

export default JavaScriptBasics;
